package org.wattdepot.cli.command;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Implements the TotalPowerCommand handler.
 * 
 * @author Yichi Xu
 * 
 */
public class TotalPowerCommand extends WattDepotCliCommand {
  /**
   * Creates an instance of the TotalPower command handler.
   * 
   * @param client An instance of the WattDepotClient.
   */
  public TotalPowerCommand(WattDepotClient client) {
    super(client);
  }

  /**
   * Performs the command.
   * 
   * @param command The command to process.
   * @return The result of the command.
   */
  @Override
  public String doCommand(String command) {
    StringTokenizer tokenizer = new StringTokenizer(command);
    List<String> tokens = new ArrayList<String>();
    XMLGregorianCalendar timestamp = null;

    while (tokenizer.hasMoreTokens()) {
      tokens.add(tokenizer.nextToken());
    }

    if (!"totalpower".equals(tokens.get(0))) {
      return WattDepotCliCommand.reportUnknownCommand(command);
    }
    
    if (tokens.size() != 5) {
      return this.reportError(PARAMETER_COUNT_ERROR);
    }
    
    if (!"fueltype".equals(tokens.get(3))) {
      return this.reportError(PARAMETER_ERROR + tokens.get(3));
    }
    
    try {
      timestamp = Tstamp.makeTimestamp(tokens.get(2));
    }
    catch (Exception ex) {
      return this.reportError(TSTAMP_ERROR + tokens.get(2));
    }

    try {
      return this.getTotalPowerFuelType(tokens.get(1), timestamp, tokens.get(4));
    }
    catch (ResourceNotFoundException ex) {
      return this.reportError(SOURCE_ERROR + tokens.get(1));
    }
    catch (BadXmlException ex) {
      return this.reportError(BAD_XML_ERROR);
    }
    catch (Exception ex) {
      return this.reportError(CONNECTION_ERROR);
    }
  }

  /**
   * get power generated by a source and its sub-sources given the fueltype and the timestamp.
   * 
   * @param sourceName The name of the source to be summarized.
   * @param timestamp The time to retrieve the information at.
   * @param fuelType The fueltype of the source to be summarized.
   * @return amount of power generated or an error if one occurs.
   * @throws NotAuthorizedException exception
   * @throws ResourceNotFoundException exception
   * @throws BadXmlException exception
   * @throws MiscClientException exception
   */
  String getTotalPowerFuelType(String sourceName, XMLGregorianCalendar timestamp, String fuelType)
      throws NotAuthorizedException, ResourceNotFoundException, BadXmlException,
      MiscClientException {
    Source source = client.getSource(sourceName);
    StringBuffer buf = new StringBuffer();
    String tempFuelType = "fuelType";
    Double power = 0.0;
    List<Source> nonVirtualSource = new ArrayList<Source>();
    WattDepotCliCommand.getNonVirtualSources(nonVirtualSource, source, client);

    for (Source tempSource : nonVirtualSource) {
      if (fuelType.equals(tempSource.getProperty(tempFuelType))) {
        power += this.client.getPowerGenerated(tempSource.getName(), timestamp);
      }
    }

    buf.append(power.toString());
    return buf.toString();
  }

  /**
   * Gets the help string associated with the totalpower command.
   * 
   * @see org.wattdepot.cli.command.WattDepotCliCommand#getHelp()
   * @return Information on how to invoke the totalpower command.
   */
  @Override
  public String getHelp() {
    return "totalpower {source} {timestamp} fueltype {fueltype}\n"
        + "  Prints information about the power generated by a source given a fueltype.\n";
  }
}
